/**
 * AXIOS 文档
 * https://www.kancloud.cn/yunye/axios/234845
 */
import axios from 'axios'
import { InterceptorManager } from './InterceptorManager';
import settings from "@/settings";
export const HTTP_METHOD_GET = 'GET';
export const HTTP_METHOD_POST = 'POST';
const services = [];
// 当前是否为调试模式
const isDebug = settings.parse('debug') === true;
export const interceptors = {
  request: new InterceptorManager(services, 'request'),
  response: new InterceptorManager(services, 'response')
};
export const Requester = (options, mockFn) => {
  options.headers = options.headers || {};
  if (!options.headers['Content-Type']) {
    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
  }
  let isMock = false;
  if (!mockFn) {
    mockFn = () => { }
  } else {
    isMock = true;
  }

  let service = axios.create(options);
  services.push(service);

  service.interceptors.request.use(config => {
    config.baseURL = options.baseURL;
    const transformRequest = (data) => {
      if (!data) { return }
      let keys = Object.keys(data);
      // 判断请求中是否包含文件
      let hasFile = Object.values(data).find(p => p instanceof File);
      if (hasFile) {
        // 请求包含文件 -> 采用 FormData 方式提交
        let formData = new FormData();
        keys.forEach(key => {
          formData.append(key, data[key]);
        });
        return formData;
      } else {
        // 请求中不包含文件 -> 默认方式提交
        let params = [];
        keys.forEach(key => {
          let name = encodeURIComponent(key);
          let value = encodeURIComponent(data[key]);
          params.push(`${name}=${value}`);
        });
        return params.join("&")
      }
    }
    config.transformRequest = [transformRequest];
    return config;
  });

  service.interceptors.response.use(response => {
    const result = response.data;
    // 仅在调试模式状态下输出请求日志
    if (isDebug && isMock) {
      const { config } = response;
      console.group(config.method, config.url);
      switch (config.method) {
        case "get":
          console.debug("params", { ...config.params });
          break;
        case "post":
          console.debug("params", config.data);
          break;
      }
      console.debug("response", result);
      console.groupEnd(config.method, config.url);
    }
    return response;
  }, error => {
    const notice = { ret: -1, title: '', desc: '' };
    const { response, message } = error;
    if (response) {
      notice.title = "服务器异常";
      const { status } = response;
      switch (status) {
        case 400: notice.desc = '请求错误(400)'; break;
        case 401: notice.desc = '未授权，请重新登录(401)'; break;
        case 403: notice.desc = '拒绝访问(403)'; break;
        case 404: notice.desc = '请求的资源不存在(404)'; break;
        case 408: notice.desc = '请求超时(408)'; break;
        case 500: notice.desc = '服务器错误(500)'; break;
        case 501: notice.desc = '服务未实现(501)'; break;
        case 502: notice.desc = '网络错误(502)'; break;
        case 503: notice.desc = '服务不可用(503)'; break;
        case 504: notice.desc = '网络超时(504)'; break;
        case 505: notice.desc = 'HTTP版本不受支持(505)'; break;
        default: notice.desc = `连接出错(${status})!`;
      }
    } else {
      notice.title = "请求异常";
      switch (message) {
        case 'Network Error': notice.desc = "无法连接服务器，请求发送失败。"; break;
        default: notice.desc = message; break;
      }
    }
    return Promise.reject(notice);
  });

  mockFn(service);

  const build = (api, data, method) => {
    let options = { url: api, method };
    switch (method) {
      case HTTP_METHOD_GET:
        options.params = data;
        break;
      case HTTP_METHOD_POST:
        options.data = data;
        break;
    }
    return service(options);
  }

  return {
    build,
    interceptors: service.interceptors,
    AXIOS: url => axios({ url, method: HTTP_METHOD_GET }),
    GET: (api, data) => build(api, data, HTTP_METHOD_GET),
    POST: (api, data) => build(api, data, HTTP_METHOD_POST)
  }
}
